import React, { createContext, useEffect, useRef, useState } from 'react';
import {
  Button,
  Card,
  Col,
  Form,
  Input,
  message,
  Popconfirm,
  Row,
  Select,
  Table,
  Upload,
} from 'antd';
import { formItemLayout } from '@/support/constant/common';
import AddDir from './addDir';
import { useAntdTable } from 'ahooks';
import styles from './style.less';
import {
  contentDirList,
  copyContentDir,
  deleteContentDir,
  publishContentDir,
  sortContentDir,
} from '@/services/contentMng/contentDirectory';
import router from 'umi/router';
import { useLocation } from 'react-router-dom';
import { isJson } from '@/utils/common';
import { ColumnsType } from 'antd/es/table';
import { ContentDirListItem } from '@/types/contentMng/contentDirectory';
import Edit from './edit';
import Detail from './detail';
import dayjs from 'dayjs';
import { contentTemplateCopy } from '@/services/contentMng/contentTempList';
import { orderBy } from 'lodash';
import MaskText from '@/components/MaskText';
interface ContextFields {
  dirConfig: string | null;
  tempId: string | null;
}

export const DirContext = createContext<ContextFields>({
  dirConfig: '{}',
  tempId: '',
});
const releaseStateMap = new Map([
  [0, '未发布'],
  [1, '已发布'],
  [2, '已下架'],
]);

enum PublishStatusEnum {
  UnPublish = 0,
  Publish = 1,
  Remove = 2,
}

const releaseStateOptions: any[] = [];
for (let [value, label] of releaseStateMap.entries()) {
  releaseStateOptions.push({ label, value });
}

type CustomDirListItem = ContentDirListItem & {
  parentIndex: number;
  children?: CustomDirListItem[];
};
function listToTree(list: ContentDirListItem[]) {
  let map: { [prop: string]: number } = {},
    node: CustomDirListItem,
    tree = [],
    i: number;
  for (i = 0; i < list.length; i++) {
    map[list[i].sid] = i; // 初始化映射
  }

  for (i = 0; i < list.length; i++) {
    node = list[i] as CustomDirListItem;
    if(node.parentSid === 0 ) {
      node.parentIndex = node.parentSid;
      tree.push(node); // 没有父节点，则加入到树结构中
    } else {
      // map[node.parentSid]的值可能是0
      if(map[node.parentSid] !== undefined) {
      // 判断是否有父节点
        let parentIndex = map[node.parentSid];
        let parentNode = list[parentIndex] as CustomDirListItem;
        let children = (parentNode.children = parentNode.children || []);
        node.parentIndex = parentIndex;
        children.push(node);
      } else {
        node.parentIndex = node.parentSid;
        tree.push(node); // 没有父节点，则加入到树结构中
      }
    }
  }
  return tree;
}

enum ModalEnum {
  Close = 'Close',
  AddDir = 'AddDir',
  Edit = 'Edit',
  Detail = 'Detail',
}

const Index = () => {
  const { query } = useLocation() as any;

  const dirConfigStr = sessionStorage.getItem('dirConfig');
  const contentListInfoStr = sessionStorage.getItem('contentListInfo');
  const dirConfig = isJson(dirConfigStr) ? JSON.parse(dirConfigStr!) : {};
  const contentListInfo = isJson(dirConfigStr) ? JSON.parse(contentListInfoStr!) : {};
  const tempId = query.tempId || contentListInfo.tempId;
  const rawTableList = useRef<ContentDirListItem[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [copyInfo, setCopyInfo] = useState<null | any>(null);
  const [modalInfo, setModalInfo] = useState<{
    name: ModalEnum;
    level: number;
    data: null | CustomDirListItem;
  }>({
    name: ModalEnum.Close,
    level: 0,
    data: null,
  });
  const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
  const [form] = Form.useForm();

  const getTableData = async ({ current, pageSize }, formData: any) => {
    let { data: list } = await contentDirList({ ...formData });
    /* 
      1. 已发布的在最上面，未发布和已下架的在下面
      2. 已发布的，orderNo 升序
      3. 已发布，未进行过手动调整顺序的，按照更新时间排序. 升序
    */
    let sortList = orderBy(list, [(record) => {
      // 1. 已发布的在最上面，未发布和已下架的在下面
      let { publishStatus } = record;
      if(publishStatus === 1) return publishStatus * 10;
      return publishStatus;
    },'orderNo', 'updateTime'],['desc','asc', 'asc' ]);
    rawTableList.current = sortList;
    let treeList = listToTree(sortList);
    return {
      list: treeList,
      total: 10,
    };
  };

  const { tableProps, search } = useAntdTable(getTableData, {
    form,
    defaultPageSize: 1000,
  });

  useEffect(() => {
    const getExpandedKey = (list: any[], keys: string[]) => {
      list.forEach((item => {
        if(Array.isArray(item.children) && item.children.length >0) {
          keys.push(item.sid);
          getExpandedKey(item.children, keys);
        }
      }))
      return keys;
    }
    setExpandedRowKeys(getExpandedKey(tableProps.dataSource, []))
  }, [tableProps.dataSource])

  const { submit, reset } = search;

  const refresh = () => {
    submit();
  };

  const getCopyInfo = () => {
    const contentCopyInfoStr = sessionStorage.getItem('contentCopyInfo');
    const contentCopyInfo = isJson(contentCopyInfoStr) ? JSON.parse(contentCopyInfoStr!) : {};
    const { type, data } = contentCopyInfo;
    switch (type) {
      case 'copyAll':
        if (!data?.dirConfig) {
          // 如果不存在目录形式，不允许粘贴
          setCopyInfo(null);
          return;
        }
        setCopyInfo({
          type: 'copyAll',
          data: {
            templateSid: data.sid,
          },
        });
        break;
      case 'copyDirectory':
        setCopyInfo(contentCopyInfo);
        break;
      default:
        break;
    }
  };

  useEffect(() => {
    getCopyInfo();
  }, []);

  // 新增目录
  const onAddDir = (record: any) => {
    setModalInfo({
      name: ModalEnum.AddDir,
      level: (record.catalogueLevel || 0) + 1,
      data: record,
    });
  };

  const onPasteDir = async () => {
    if (!copyInfo) {
      return;
    }
    const { data, type } = copyInfo;
    let result = null;
    if (type === 'copyAll') {
      let params = {
        templateSid: data.templateSid,
        pasteTemplateSid: tempId,
      };
      result = await contentTemplateCopy(params);
    } else if (type === 'copyDirectory') {
      let params = {
        dirList: data.catalogueSids,
        pasteTemplateSid: tempId,
      };
      result = await copyContentDir(params);
    }

    if (result.statusCode == '0') {
      message.success('粘贴成功');
      refresh();
      sessionStorage.removeItem('contentCopyInfo');
      setCopyInfo(null);
    }
  };

  const onCopyDir = () => {
    if (!selectedRowKeys.length) {
      message.warning('请先勾选目录');
      return;
    }

    const copyInfo = {
      type: 'copyDirectory',
      data: {
        templateSid: tempId,
        catalogueSids: selectedRowKeys,
      },
    };
    sessionStorage.setItem('contentCopyInfo', JSON.stringify(copyInfo));
    setSelectedRowKeys([]);
    setCopyInfo(copyInfo);
    message.success('已复制勾选目录，可在新增或升级内容时粘贴');
  };

  const onClose = (options?: { isRefresh: boolean }) => {
    if (options && options.isRefresh) refresh();
    setModalInfo({ name: ModalEnum.Close, level: 0, data: null });
  };

  // 详情
  const onDetail = (record: CustomDirListItem) => {
    setModalInfo({
      name: ModalEnum.Detail,
      level: (record.catalogueLevel || 0) + 1,
      data: record,
    });
  };

  // 编辑
  const onEdit = (record: CustomDirListItem) => {
    setModalInfo({
      name: ModalEnum.Edit,
      level: (record.catalogueLevel || 0) + 1,
      data: record,
    });
  };

  // 发布或取消发布
  const onPublish = async (record: CustomDirListItem, publishStatus: PublishStatusEnum) => {
    const { sid } = record;
    let msgTxt = publishStatus === PublishStatusEnum.Publish ? '发布成功' : '取消发布成功';
    let result = await publishContentDir({ sid, publishStatus });
    if (result.statusCode === '0') {
      message.success(msgTxt);
      refresh();
    }
  };

  // 内容管理
  const contentManage = record => {
    router.push(`/contentMng/contentList?dirSid=${record.sid}`);
  };

  // 删除
  const onDelete = async (record: CustomDirListItem) => {
    let res = await deleteContentDir({ sid: record.sid });
    if (res.statusCode === '0') {
      message.success('删除目录成功');
      refresh();
    }
  };

  // 排序
  const onSort = async (record: CustomDirListItem, sortType: string) => {
    let { parentIndex, sid } = record;
    let sameLevelList =
      parentIndex === 0
        ? rawTableList.current.filter(item => item.parentSid === 0)
        : rawTableList.current[parentIndex]?.children || [];

    const directoryReleaseList = sameLevelList.filter(i => i.publishStatus == 1);
    const currentIndex = directoryReleaseList.findIndex(i => i.sid == sid);
    // 位置互换 test
    if (sortType === 'up') {
      directoryReleaseList[currentIndex] = directoryReleaseList[currentIndex - 1];
      directoryReleaseList[currentIndex - 1] = record;
    } else if (sortType === 'down') {
      directoryReleaseList[currentIndex] = directoryReleaseList[currentIndex + 1];
      directoryReleaseList[currentIndex + 1] = record;
    }
    const params = directoryReleaseList.map((directory, index) => {
      return {
        sid: directory.sid,
        orderNo: index + 1,
      };
    });
    let res = await sortContentDir(params);
    if (res.statusCode === '0') {
      message.success('操作成功');
      refresh();
    }
  };
  const columns: ColumnsType<CustomDirListItem> = [
    {
      title: '目录名称',
      dataIndex: 'catalogueName',
      key: 'catalogueName',
      width: '30%'
    },
    {
      title: '发布状态',
      dataIndex: 'publishStatus',
      key: 'publishStatus',
      align: 'center',
      width: '10%',
      render(value) {
        return releaseStateMap.get(value);
      },
    },
    {
      title: '更新人',
      dataIndex: 'updateBy',
      key: 'updateBy',
      align: 'center',
      width: '10%',
      render(value) {
        return <MaskText text={value} type='name' />
      }
    },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      key: 'updateTime',
      align: 'center',
      width: '20%',
      render(value) {
        if (value === null || value === undefined) {
          return '--';
        }
        return dayjs(value).format('YYYY-MM-DD HH:mm:ss');
      },
    },
    {
      title: '操作',
      key: 'opera',
      align: 'center',
      render(value, record: CustomDirListItem, index) {
        let { publishStatus, children } = record;
        const showBtns =
          publishStatus === 1
            ? [
                {
                  label: '详情',
                  fn: onDetail,
                  key: 'detail',
                },
                {
                  label: '取消发布',
                  fn: () => onPublish(record, PublishStatusEnum.Remove),
                  key: 'cancelPublish',
                },
              ]
            : [
                {
                  label: '编辑',
                  fn: onEdit,
                  key: 'edit',
                },
                {
                  label: '发布',
                  fn: () => onPublish(record, PublishStatusEnum.Publish),
                  key: 'publish',
                },
              ];
        let currentList = [];
        if (record.parentSid === 0) {
          currentList = tableProps.dataSource;
        } else {
          currentList = rawTableList.current[record.parentIndex]?.children || [];
        }
        let publishList = currentList.filter(
          item => item.publishStatus === PublishStatusEnum.Publish,
        );
        let currentIndex = publishList.findIndex(item => item.sid === record.sid);

        // 子目录按钮：非末级目录才显示
        const childDir = dirConfig.filter(item => item.level > record.catalogueLevel);

        return (
          <div className={styles['table-opera-btns']}>
            {record.publishStatus === 1 && currentIndex > 0 && (
              <span key="moveUp" onClick={() => onSort(record, 'up')}>
                上移
              </span>
            )}
            {record.publishStatus === 1 && currentIndex + 1 < publishList.length && (
              <span key="moveDown" onClick={() => onSort(record, 'down')}>
                下移
              </span>
            )}
            {showBtns.map(item => {
              return (
                <span onClick={() => item.fn(record)} key={item.key}>
                  {item.label}
                </span>
              );
            })}
            {record.publishStatus !== 1 && (!Array.isArray(children) || children.length === 0) && (
              <Popconfirm
                title="您确定要删除吗？"
                onConfirm={() => onDelete(record)}
                okText="确定"
                cancelText="取消"
                key={'delete'}
              >
                <span>删除</span>
              </Popconfirm>
            )}
            {childDir.length > 0 ? (
              <span onClick={() => onAddDir(record)} key={'addChildDir'}>
                添加子目录
              </span>
            ) : (
              <span onClick={() => contentManage(record)} key={'contentManage'}>
                内容管理
              </span>
            )}
          </div>
        );
      },
    },
  ];

  const getAllChildSid = (data: any): any => {
    let result = [];
    const children = data.children;
    if (children) {
      for (let index = 0; index < children.length; index++) {
        const childDir = children[index];
        result.push(childDir.sid);
        if (childDir.children) {
          result.push(...getAllChildSid(childDir));
        }
      }
    }
    return result;
  };

  const rowSelection = {
    selectedRowKeys,
    onChange: (selectedRowKeys: React.Key[]) => {
      setSelectedRowKeys(selectedRowKeys);
    },
  };

  const onBack = () => {
    router.push('/contentMng/contentTempList');
  };

  const onExpandedRowsChange = (expandedRows: string[]) => {
    setExpandedRowKeys(expandedRows)
  }


  return (
    <div>
      <Card>
        <Form form={form} {...formItemLayout}>
          <Row>
            <Col span={0}>
              <Form.Item label="目录所属模版sid" name="templateSid" hidden initialValue={tempId}>
                <Input />
              </Form.Item>
            </Col>
            <Col span={8}>
              <Form.Item label="目录名称" name="catalogueName">
                <Input placeholder="请输入目录名称" allowClear />
              </Form.Item>
            </Col>
            <Col span={8}>
              <Form.Item label="发布状态" name="publishStatus">
                <Select placeholder="请输入内容名称" options={releaseStateOptions} allowClear />
              </Form.Item>
            </Col>
            <Col span={8}>
              <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
                <Button onClick={submit} type="primary" size="small">
                  查询
                </Button>
                <Button onClick={reset} size="small" style={{ margin: '0 16px' }}>
                  重置
                </Button>
              </div>
            </Col>
          </Row>
        </Form>
      </Card>
      <Card className={styles['table-card']}>
        <div className={styles['table-head-btns']}>
          <Button type="primary" onClick={() => onAddDir({ sid: 0 })}>
            新增一级目录
          </Button>
          {copyInfo && (
            <Button type="primary" onClick={onPasteDir}>
              粘贴目录
            </Button>
          )}
          <Button type="primary" onClick={onCopyDir}>
            复制目录
          </Button>
        </div>
        <Table
          columns={columns}
          {...tableProps}
          rowKey={'sid'}
          rowSelection={{ ...rowSelection, checkStrictly: false }}
          expandable={{ expandedRowKeys, onExpandedRowsChange }}
          pagination={false}
          scroll={{ x: "max-content" }}
        />
        <div>
          <Button onClick={onBack} type="primary">
            返回
          </Button>
        </div>
      </Card>
      <AddDir
        open={modalInfo.name === ModalEnum.AddDir}
        onClose={onClose}
        tempId={tempId}
        level={modalInfo.level}
        data={modalInfo.data}
      />

      <Edit open={modalInfo.name === ModalEnum.Edit} onClose={onClose} data={modalInfo.data} />
      <Detail open={modalInfo.name === ModalEnum.Detail} onClose={onClose} data={modalInfo.data!} />
    </div>
  );
};

export default Index;
